// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.network;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.HashSet;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import zombie.core.znet.PortMapper;
import zombie.core.znet.SteamGameServer;
import zombie.core.znet.SteamUtils;
import zombie.debug.DebugLog;

public class CoopSlave {
    private static PrintStream stdout;
    private static PrintStream stderr;
    private Pattern serverMessageParser;
    private long nextPing = -1L;
    private long lastPong = -1L;
    public static CoopSlave instance;
    public String hostUser = null;
    public long hostSteamID = 0L;
    private boolean masterLost = false;
    private HashSet<Long> invites = new HashSet();
    private Long serverSteamID = null;

    public static void init() throws FileNotFoundException {
        instance = new CoopSlave();
    }

    public static void initStreams() throws FileNotFoundException {
        FileOutputStream fileOutputStream = new FileOutputStream(zombie.ZomboidFileSystem.instance.getCacheDir() + File.separator + "coop-console.txt");
        stdout = System.out;
        stderr = System.err;
        System.setOut(new PrintStream(fileOutputStream));
        System.setErr(System.out);
    }

    private CoopSlave() {
        this.serverMessageParser = Pattern.compile("^([\\-\\w]+)(\\[(\\d+)\\])?@(.*)$");
        this.notify("coop mode enabled");
        if (System.getProperty("hostUser") != null) {
            this.hostUser = System.getProperty("zomboid.hostUser").trim();
        }
    }

    public synchronized void notify(String notification) {
        this.sendMessage("info", null, notification);
    }

    public synchronized void sendStatus(String status) {
        this.sendMessage("status", null, status);
    }

    public static void status(String status) {
        if (instance != null) {
            instance.sendStatus(status);
        }
    }

    public synchronized void sendMessage(String message) {
        this.sendMessage("message", null, message);
    }

    public synchronized void sendMessage(String tag, String cookie, String payload) {
        if (cookie != null) {
            stdout.println(tag + "[" + cookie + "]@" + payload);
        } else {
            stdout.println(tag + "@" + payload);
        }
    }

    public void sendExternalIPAddress(String cookie) {
        this.sendMessage("get-parameter", cookie, PortMapper.getExternalAddress());
    }

    public synchronized void sendSteamID(String cookie) {
        if (this.serverSteamID == null && SteamUtils.isSteamModeEnabled()) {
            this.serverSteamID = SteamGameServer.GetSteamID();
        }

        this.sendMessage("get-parameter", cookie, this.serverSteamID.toString());
    }

    public boolean handleCommand(String command) {
        Matcher matcher = this.serverMessageParser.matcher(command);
        if (matcher.find()) {
            String string0 = matcher.group(1);
            String string1 = matcher.group(3);
            String string2 = matcher.group(4);
            if (Objects.equals(string0, "set-host-user")) {
                System.out.println("Set host user:" + string2);
                this.hostUser = string2;
            }

            if (Objects.equals(string0, "set-host-steamid")) {
                this.hostSteamID = SteamUtils.convertStringToSteamID(string2);
            }

            if (Objects.equals(string0, "invite-add")) {
                Long long0 = SteamUtils.convertStringToSteamID(string2);
                if (long0 != -1L) {
                    this.invites.add(long0);
                }
            }

            if (Objects.equals(string0, "invite-remove")) {
                Long long1 = SteamUtils.convertStringToSteamID(string2);
                if (long1 != -1L) {
                    this.invites.remove(long1);
                }
            }

            if (Objects.equals(string0, "get-parameter")) {
                DebugLog.log("Got get-parameter command: tag = " + string0 + " payload = " + string2);
                if (Objects.equals(string2, "external-ip")) {
                    this.sendExternalIPAddress(string1);
                } else if (Objects.equals(string2, "steam-id")) {
                    this.sendSteamID(string1);
                }
            }

            if (Objects.equals(string0, "ping")) {
                this.lastPong = System.currentTimeMillis();
            }

            if (Objects.equals(string0, "process-status") && Objects.equals(string2, "eof")) {
                DebugLog.log("Master connection lost: EOF");
                this.masterLost = true;
            }

            return true;
        } else {
            DebugLog.log("Got malformed command: " + command);
            return false;
        }
    }

    public String getHostUser() {
        return this.hostUser;
    }

    public void update() {
        long long0 = System.currentTimeMillis();
        if (long0 >= this.nextPing) {
            this.sendMessage("ping", null, "ping");
            this.nextPing = long0 + 5000L;
        }

        long long1 = 60000L;
        if (this.lastPong == -1L) {
            this.lastPong = long0;
        }

        this.masterLost = this.masterLost || long0 - this.lastPong > long1;
    }

    public boolean masterLost() {
        return this.masterLost;
    }

    public boolean isHost(long steamID) {
        return steamID == this.hostSteamID;
    }

    public boolean isInvited(long friendSteamID) {
        return this.invites.contains(friendSteamID);
    }
}
